-
-
Notifications
You must be signed in to change notification settings - Fork 118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Matchinfo lifetime #1225
Matchinfo lifetime #1225
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, looks mostly good to me :)
glib/src/match_info.rs
Outdated
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
#[repr(transparent)] | ||
pub struct MatchInfo<'input> { | ||
inner: crate::shared::Shared<ffi::GMatchInfo, Self>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inner: crate::shared::Shared<ffi::GMatchInfo, Self>, | |
inner: std::ptr::NonNull<ffi::GMatchInfo>, |
should be sufficient or not? Then the SharedMemoryManager
noise below can also go away
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would work too, but would require manually implementing the reference-counting logic that Shared
already implements, i.e. calling g_match_info_ref
in clone
instead of deriving Clone
, and implementing Drop
to call g_match_info_unref
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the question then is which is simpler. Your call
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went with using NonNull
and manually implementing the reference counting, since Shared
also caused issues with variance (Shared<_, MM>
is invariant in MM
, meaning holding a Shared<_, Self>
in MatchInfo<'input>
causes MatchInfo
to be invariant in 'input
, when ideally it should be covariant).
glib/src/shared.rs
Outdated
@@ -527,7 +527,7 @@ impl<T, MM: SharedMemoryManager<Target = T>> Hash for Shared<T, MM> { | |||
|
|||
impl<'a, T: 'static, MM> ToGlibPtr<'a, *mut T> for Shared<T, MM> | |||
where | |||
MM: SharedMemoryManager<Target = T> + 'static, | |||
MM: SharedMemoryManager<Target = T> + 'a, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably go into a separate commit (in the same PR). Is the same change needed for src/boxed.rs
too, for example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, we need that for gtk-rs/gtk4-rs#1280
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That bug is basically the same thing as this one here, yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is no longer part of this PR, since I now implement the reference counting manually instead of using SharedMemoryManager
/Shared<P, MM>
due to variance (#1225 (comment))
617fa8e
to
8abb00d
Compare
8abb00d
to
fe601ef
Compare
Okay, now that |
glib/src/match_info.rs
Outdated
type BuilderFn = fn(&str) -> crate::ParamSpecBoxedBuilder<Self>; | ||
|
||
fn param_spec_builder() -> Self::BuilderFn { | ||
|name| Self::ParamSpec::builder(name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error: redundant closure
--> glib/src/match_info.rs:267:9
|
267 | |name| Self::ParamSpec::builder(name)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `Self::ParamSpec::builder`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure
= note: `-D clippy::redundant-closure` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, looks good to me. Can you squash it all into a single commit with a meaningful commit message? Then I'll merge it :)
Implement MatchInfo manually. Manually implements refcounting and from/into glib ptrs instead of using crate::shared::Shared, since using Shared<_, Self> causes the lifetime parameter to be invariant instead of covariant. Removes array/slice conversions for `MatchInfo`. ValueType/ToValue/HasParamSpec impls are restricted to `MatchInfo<'static>` to avoid use-after-free by converting `MatchInfo<'short>` to `Value`. FromValue is implemented for MatchInfo for any lifetime, since MatchInfo is covariant anyway.
ea24437
to
2fd6046
Compare
May fix #1223
Adds a (covariant) lifetime parameter to
glib::MatchInfo
, and restricts theglib::Regex
methods that returnMatchInfo
to taking only&'input GStr
as input (instead ofimpl IntoGStr
) and returningMatchInfo<'input>
that borrows from the input. AlsoMatchInfo::string
now returns a borrowed&'input GStr
instead of an ownedGString
.Manually implements the
MatchInfo
struct and related traits since thewrapper!
macro does not support lifetime generics (I used rust-analyzer's "expand macro recursively" option on the previous autogenerated impl using thewrapper!
macro, copy-pasted it, and modified it as needed.)Removes theValueType
/ToValue
/FromValue
impls fromMatchInfo
as they would be unsound (could be used to "extend" the borrowed lifetime; seeglib/tests/regex_compiletest/04-no-to-value.rs
). Also removes theHasParamSpec
impl forMatchInfo
1.Relaxes theToGlibPtr<'a, *mut T> for Shared<T, MM>
impl's lifetime bound to only boundMM: 'a
instead ofMM: 'static
so thatMatchInfo
can still use it. The methods in this trait return raw pointers, and the methods in theFromGlibPtr
trait which take these pointers isunsafe
, so I believe this should be fine.Restricts the
ValueType
/ToValue
/HasParamSpec
impls toMatchInfo<'static>
.FromValue<'a>
is implemented forMatchInfo
for all lifetimes (longer than'a
).Manually implements the reference counting instead of using
glib::shared::Shared
, since otherwise caused issues with variance2.Footnotes
I removed the↩HasParamSpec
impl forMatchInfo
mostly because it "seemed" wrong; I haven't come up with a concrete example of unsoundness it could cause withoutFromValue
/ToValue
also being implemented.(
Shared<_, MM>
is invariant inMM
, meaning holding aShared<_, Self>
inMatchInfo<'input>
causesMatchInfo
to be invariant in'input
) ↩